﻿using RayDen.Library.Components.Surface;
using RayDen.Library.Core;
using RayDen.Library.Core.Primitives;
using RayDen.RayEngine.Core.Types;
using RayDen.RayEngine.Data;

namespace RayDen.RayEngine.Engines.ProgressivePhotonMapping {

    public enum HitPointType {
        Constant,
        Surface,
        Volume,
    };

    public class PPMHitPoint 
    {
        public HitPointType type; //4

        public float scrX, scrY;//8
        public int pass; //4

        // Used for CONSTANT_COLOR and SURFACE type
        public RgbSpectrum throughput;//12

        // Used for SURFACE type
        public Point position;//12
        public Vector wo;//12
        public Normal normal;//12
        public ISurfaceMaterial material;//4

        public float photonRadius2;//4
        public int accumPhotonCount;//4
        public RgbSpectrum accumReflectedFlux, accumDirectLightRadiance, radiance;//12
        public float pathWeight;//4
    }


    public static class SampleBufferExtensions
    {
        public static void SampleHitPoint(this SampleBuffer sampleBuffer, PPMHitPoint hp, int photonTraced)
        {
            switch (hp.type)
            {
                case HitPointType.Constant:
                    {
                        sampleBuffer.SplatSample(hp.scrX, hp.scrY,ref hp.throughput);
                        break;
                    }
                case HitPointType.Surface:
                    {
                        var rad = RgbSpectrum.ZeroSpectrum();
                        if (hp.accumPhotonCount == 0)
                        {                            
                            sampleBuffer.SplatSample(hp.scrX, hp.scrY,ref rad);
                        }
                        else
                        {
                            float k = 1.0f / (MathLab.M_PI * hp.photonRadius2 * photonTraced);
                            rad = hp.accumReflectedFlux * k;
                            sampleBuffer.SplatSample(hp.scrX, hp.scrY, ref rad);
                        }
                        break;
                    }
            }
        }

    }
}